#pragma once

#include <cstring>
#include <functional>
#include <memory>
#include <string>

#include "qconf.h"

namespace qio {

class WriteBuf;

using SharedWriteBuf = std::shared_ptr<WriteBuf>;

class WriteBuf final {
 public:
  /**
   * @brief 写回调
   * @param WriteBuf* 实例
   * @param bool 是否写成功
   */
  using DoneCallback = std::function<void(WriteBuf *, bool)>;

 public:
  ~WriteBuf() QIO_NOEXCEPT;

  /**
   * WriteBuf
   * data 数据必须是 new[] 产生的,否则该类在 own = true 时的析构函数 UB
   * @param data 数据
   * @param data_len 数据长度
   * @param own true 则 data 将会被WriteBuf托管,脱离用户控制权
   * @param cb 写入成功回调
   */
  WriteBuf(const char *data, std::size_t data_len, bool own,
           DoneCallback &&cb) QIO_NOEXCEPT;

  inline const char *Data() const QIO_NOEXCEPT { return data_; }

  inline std::size_t DataLen() const QIO_NOEXCEPT { return data_len_; }

  inline void SetWriteIndex(std::size_t idx) QIO_NOEXCEPT { write_idx_ = idx; }

  inline std::size_t WriteIndex() const QIO_NOEXCEPT { return write_idx_; }

  DISABLE_CPY(WriteBuf)

  // enable move
  WriteBuf(WriteBuf &&o) QIO_NOEXCEPT;

  WriteBuf &operator=(WriteBuf &&) QIO_NOEXCEPT;

 private:
  bool own_;
  std::size_t data_len_;
  const char *data_;
  DoneCallback write_result_cb_;
  std::size_t write_idx_;
};

using WriteDoneCallback = WriteBuf::DoneCallback;

}  // namespace qio
